﻿using BUGCOME.Infrastructure.Attribute;
using BUGCOME.Model.Common;
using BUGCOME.Model.Common.dto;
using BUGCOME.Repository;
using BUGCOME.Service.Common.IServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BUGCOME.Service.Common
{
    /// <summary>
    /// 多语言配置Service业务层处理
    /// @author bugcome
    /// @date 2022-05-06
    /// </summary>
    [AppService(ServiceType = typeof(ILangService), ServiceLifetime = LifeTime.Transient)]
    public class LangService : BaseService<Lang>, ILangService
    {
        #region 业务逻辑代码

        /// <summary>分页查询多语言配置列表</summary>
        public async Task<PagedInfo<Lang>> GetListAsync(LangQueryDto parm)
        {
            // 构建查询条件
            var predicate = Expressionable.Create<Lang>();
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangCode), it => it.LangCode == parm.LangCode);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangKey), it => it.LangKey.Contains(parm.LangKey));
            predicate = predicate.AndIF(parm.BeginAddtime != null, it => it.Addtime >= parm.BeginAddtime && it.Addtime <= parm.EndAddtime);

            // 执行分页查询
            return await Queryable().Where(predicate.ToExpression()).ToPageAsync<Lang>(parm);
        }

        /// <summary>将多语言数据行转列</summary>
        public  async Task<dynamic> GetListToPivotAsync(LangQueryDto parm)
        {
            // 构建查询条件
            var predicate = Expressionable.Create<Lang>();
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangCode), it => it.LangCode == parm.LangCode);
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangKey), it => it.LangKey.Contains(parm.LangKey));
            predicate = predicate.AndIF(parm.BeginAddtime != null, it => it.Addtime >= parm.BeginAddtime && it.Addtime <= parm.EndAddtime);

            // 执行行转列查询
            return await Queryable().Where(predicate.ToExpression())
                .ToPivotListAsync(it => it.LangCode, it => it.LangKey, it => it.Max(f => f.LangName));
        }

        /// <summary>获取多语言配置列表</summary>
        public async Task<List<Lang>> GetLangListAsync(LangQueryDto parm)
        {
            // 构建查询条件
            var predicate = Expressionable.Create<Lang>();
            predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangCode), it => it.LangCode == parm.LangCode);

            // 执行查询并返回列表
            return await Queryable().Where(predicate.ToExpression()).ToListAsync();
        }

        /// <summary>存储多语言配置</summary>
        public async Task StorageLangAsync(LangDto parm)
        {
            // 转换DTO为实体列表
            List<Lang> langs = parm.LangList.Select(item => new Lang
            {
                Addtime = DateTime.Now,
                LangKey = parm.LangKey,
                LangCode = item.LangCode,
                LangName = item.LangName
            }).ToList();

            // 执行批量新增或更新
            var storage = Context.Storageable(langs).WhereColumns(it => new { it.LangKey, it.LangCode }).ToStorage();
            storage.AsInsertable.ExecuteReturnSnowflakeIdList();
            await storage.AsUpdateable.UpdateColumns(it => new { it.LangName }).ExecuteCommandAsync();
        }

        /// <summary>转换多语言列表为字典</summary>
        public Dictionary<string, object> SetLang(List<Lang> msgList)
        {
            var dic = new Dictionary<string, object>();
            foreach (var item in msgList)
            {
                if (!dic.ContainsKey(item.LangKey))
                    dic.Add(item.LangKey, item.LangName);
            }
            return dic;
        }

        /// <summary>导入多语言配置</summary>
        public async Task<(string, object, object)> ImportLangAsync(List<Lang> list)
        {
            // 执行批量导入（新增或更新）
            var storage = Context.Storageable(list).WhereColumns(it => new { it.LangKey, it.LangCode }).ToStorage();
            await storage.AsInsertable.ExecuteReturnSnowflakeIdListAsync();
            await storage.AsUpdateable.UpdateColumns(it => new { it.LangName }).ExecuteCommandAsync();

            // 构建导入结果信息
            string msg = $"插入{storage.InsertList.Count} 更新{storage.UpdateList.Count} 错误数据{storage.ErrorList.Count} " +
                        $"不计算数据{storage.IgnoreList.Count} 删除数据{storage.DeleteList.Count} 总共{storage.TotalList.Count}";

            // 输出错误和忽略信息
            foreach (var item in storage.ErrorList) Console.WriteLine("错误" + item.StorageMessage);
            foreach (var item in storage.IgnoreList) Console.WriteLine("忽略" + item.StorageMessage);

            return (msg, storage.ErrorList, storage.IgnoreList);
        }

        #endregion
    }
}